﻿Imports System.Xml
''' <summary>
''' 数据采集
''' </summary>
''' <remarks></remarks>
Public Class clsDataDefine
    ''' <summary>
    ''' 获得当前行(带注释的完整文本)开始的数据树
    ''' </summary>
    ''' <param name="StrCurrentLine">带注释的完整文本</param>
    ''' <remarks>式样书：数据部-抽取过程</remarks>
    Shared Function GetDataTree(ByVal StrCurrentLine As String) As List(Of XmlElement)
        '删除末尾一个分号,注意:INCLUDE语句后面出现2个分号的可能性
        Do While StrCurrentLine.EndsWith(";")
            StrCurrentLine = StrCurrentLine.TrimEnd(New Char() {";"})
        Loop
        Dim SubLines As List(Of String) = GetSubLinesBySplitMark(StrCurrentLine, ",", SplitStyle.NoSplitMark)
        If SubLines.Count > 1 Then
            Dim SubSentence As String
            SubSentence = SubLines(0)
            SubSentence = ClearComment(SubSentence)
            Dim TokenList As New List(Of String)
            TokenList = GetSyntaxToken(SubSentence)
            If TokenList(1) = "1" Then
                '集团项目
                'DCL 1 AAA LIKE BB的情况
                '      XXX PIC'(4)9' 
                If HasTOKEN("LIKE", TokenList) Then
                    'DCL 1 AAA LIKE BB的处理
                    Dim TreeDCLList As New List(Of XmlElement)
                    TreeDCLList.Add(LIKEDCL(SubLines(0)))
                    '除去第一条
                    SubLines.RemoveAt(0)
                    '添加一个DCL头
                    SubLines(0) = "DCL " & SubLines(0)
                    If SubLines.Count = 1 Then
                        '如果只有1行的话，调用SINGLE
                        For Each dataxml As XmlElement In SingleDCL(SubLines(0))
                            TreeDCLList.Add(dataxml)
                        Next
                    Else
                        '如果有多条的话
                        TokenList = GetSyntaxToken(SubLines(0))
                        If TokenList(1) = "1" Then
                            TreeDCLList.Add(TreeDCL(SubLines))
                        Else
                            For Each dataxml As XmlElement In MultiSingleDCL(SubLines)
                                TreeDCLList.Add(dataxml)
                            Next
                        End If
                    End If
                    Return TreeDCLList
                Else
                    Dim TreeDCLList As New List(Of XmlElement)
                    TreeDCLList.Add(TreeDCL(SubLines))
                    Return TreeDCLList
                End If
            Else
                'DCL XXXX1,
                '    XXXX2,
                '   1 xxxx,
                '     3 xxxx, 
                '    XXXX3的写法
                Return MultiSingleDCL(SubLines)
            End If
        Else
            '单条数据
            Dim SubSentence As String
            SubSentence = SubLines(0)
            SubSentence = ClearComment(SubSentence)
            Dim TokenList As New List(Of String)
            TokenList = GetSyntaxToken(SubSentence)
            If HasTOKEN("LIKE", TokenList) Then
                Dim TreeDCLList As New List(Of XmlElement)
                TreeDCLList.Add(LIKEDCL(SubLines(0)))
                Return TreeDCLList
            Else
                Return SingleDCL(StrCurrentLine)
            End If
        End If
    End Function
    ''' <summary>
    ''' 对于LIKE的处理
    ''' </summary>
    ''' <param name="StrLine"></param>
    ''' <returns></returns>
    ''' <remarks>这个版本只处理LIKE在顶层的情况</remarks>
    Shared Function LIKEDCL(ByVal StrLine As String) As XmlElement
        Dim TreeDataXml As XmlElement = mXmlDocument.CreateElement("TREEDATA")
        Dim SingleLineWithOutComment As String = StrLine
        Dim SingleComment As String = String.Empty
        If GlobalCommentList.Count > 0 Then
            For Each StrComment As String In GlobalCommentList
                Dim CommentListXML As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                CommentListXML.SetAttribute("TEXT", StrComment)
                TreeDataXml.AppendChild(CommentListXML)
            Next
            GlobalCommentList.Clear()
        End If
        If InStr(StrLine, "*/") > 0 Then
            '注释内容
            SingleComment = GetComment(StrLine)
            TreeDataXml.SetAttribute("COMMENT", SingleComment)
        End If
        '实际内容(末尾 ';' 已经除去)
        SingleLineWithOutComment = ClearComment(StrLine)
        Dim StrWords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)
        TreeDataXml.SetAttribute("LayNo", 1)
        TreeDataXml = clsDataDefine.SetDataAttr(TreeDataXml, StrWords, 1)

        '查找LIKE目标
        Dim LikeNameArray As New List(Of String)
        For Each strTemp As String In TreeDataXml.GetAttribute("LIKE").Split(".")
            LikeNameArray.Add(strTemp)
        Next

        If LikeNameArray.Count = 1 Then
            For Each mDataXml As XmlElement In mDataNode.WorkStorageList
                If mDataXml.GetAttribute("NAME") = LikeNameArray(0) Then
                    For Each SubData As XmlElement In mDataXml.ChildNodes
                        TreeDataXml.AppendChild(SubData.Clone)
                    Next
                End If
            Next
        Else
            For Each mDataXml As XmlElement In mDataNode.WorkStorageList
                If mDataXml.GetAttribute("NAME") = LikeNameArray(0) Then
                    LikeNameArray.RemoveAt(0)
                    For Each SubData As XmlElement In GetDataXmlByPath(LikeNameArray, mDataXml)
                        TreeDataXml.AppendChild(SubData.Clone)
                    Next
                End If
            Next
        End If
        Return TreeDataXml
    End Function
    Public Shared Function GetDataXmlByPath(ByVal LikeNameArray As List(Of String), ByVal SearchRange As XmlElement) As XmlElement
        If LikeNameArray.Count = 1 Then
            For Each mDataXml As XmlElement In SearchRange.ChildNodes
                If mDataXml.GetAttribute("NAME") = LikeNameArray(0) Then
                    Return mDataXml
                End If
            Next
        Else
            For Each mDataXml As XmlElement In SearchRange.ChildNodes
                If mDataXml.GetAttribute("NAME") = LikeNameArray(0) Then
                    LikeNameArray.RemoveAt(0)
                    Return GetDataXmlByPath(LikeNameArray, mDataXml)
                End If
            Next
        End If
        Return Nothing
    End Function
    ''' <summary>
    ''' 对于单个数据项目进行数据树抽取
    ''' </summary>
    ''' <param name="StrLine"></param>
    ''' <remarks>式样书：数据部-抽取过程</remarks>
    Shared Function SingleDCL(ByVal StrLine As String) As List(Of XmlElement)
        'SINGLEDATA
        Dim SingleDataXml As XmlElement = mXmlDocument.CreateElement("SINGLEDATA")
        Dim SingleLineWithOutComment As String = StrLine
        Dim SingleComment As String = String.Empty
        'TODO 对于原来多行拼接起来的一个单行，对于夹在里面的注释进行整理。也可以考虑将Inti分组，加上分组注释
        '这样的话，就可以自动对长Init分段了。INIT/*AAA*/()里面的注释清除掉，不然会出现错误 
        '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
        If GlobalCommentList.Count > 0 Then
            For Each StrComment As String In GlobalCommentList
                Dim CommentListXML As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                CommentListXML.SetAttribute("TEXT", StrComment)
                SingleDataXml.AppendChild(CommentListXML)
            Next
            GlobalCommentList.Clear()
        End If
        If InStr(StrLine, "*/") > 0 Then
            '注释内容
            SingleComment = GetComment(StrLine)
            SingleDataXml.SetAttribute("COMMENT", SingleComment)
        End If
        '实际内容(末尾 ';' 已经除去)
        SingleLineWithOutComment = ClearComment(StrLine)
        Dim StrWords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)
        SingleDataXml.SetAttribute("LayNo", 1)
        SingleDataXml = clsDataDefine.SetDataAttr(SingleDataXml, StrWords, 1)

        Dim RtnSingleList As New List(Of XmlElement)
        Dim strName As String = SingleDataXml.GetAttribute("NAME")
        '(I,J,K) CHAR(10)    
        If strName.StartsWith("(") And strName.EndsWith(")") Then
            strName = Mid(strName, 2, strName.Length - 2)
            Dim strNameArray As String() = strName.Split(",")
            For Each strSubName As String In strNameArray
                Dim NewSubData As XmlElement = SingleDataXml.CloneNode(True)
                NewSubData.SetAttribute("NAME", strSubName)
                RtnSingleList.Add(NewSubData)
            Next
        Else
            RtnSingleList.Add(SingleDataXml)
        End If
        Return RtnSingleList
    End Function
    ''' <summary>
    ''' 多个单体数据写在一个行里
    ''' </summary>
    ''' <param name="SubLines"></param>
    ''' <remarks>式样书：数据部-抽取过程</remarks>
    Shared Function MultiSingleDCL(ByVal SubLines As List(Of String)) As List(Of XmlElement)
        Dim StrWords As New List(Of String)
        Dim SubSentence As String = String.Empty
        Dim SingleComment As String = String.Empty
        'DCL XXXX1,
        '    XXXX2,
        '   1 xxxx,
        '     3 xxxx, 
        '    XXXX3的写法
        Dim MultiSingleData As New List(Of XmlElement)
        '第一条肯定是SingleLine
        Dim FirstSingleDCLList As List(Of XmlElement) = SingleDCL(SubLines(0))
        '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
        If GlobalCommentList.Count > 0 Then
            For Each StrComment As String In GlobalCommentList
                Dim CommentListXML As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                CommentListXML.SetAttribute("TEXT", StrComment)
                FirstSingleDCLList.Item(0).AppendChild(CommentListXML)
            Next
            GlobalCommentList.Clear()
        End If
        For Each DataXml As XmlElement In FirstSingleDCLList
            MultiSingleData.Add(DataXml)
        Next
        Dim subloop As Byte = 1
        Do While subloop <= SubLines.Count - 1
            '注意：需要将注释去掉
            StrWords = GetSyntaxToken(ClearComment(SubLines(subloop)))
            '从第二条开始到最后一条，如果第一个词是'1'的话，则说明是一个集团项目的开始
            If StrWords(0) = "1" Then
                Dim treeList As New List(Of String)
                treeList.Add(GetComment(SubLines(subloop)) & "DCL " & ClearComment(SubLines(subloop)))
                subloop += 1
                '则将这一行，以及以下紧接着以数字开头的行收集起来，将这些行放入集团项目处理程序中去。
                Do While subloop <= SubLines.Count - 1 AndAlso IsNumeric(GetSyntaxToken(ClearComment(SubLines(subloop)))(0))
                    treeList.Add(SubLines(subloop))
                    subloop += 1
                Loop
                MultiSingleData.Add(TreeDCL(treeList))
            Else
                For Each DataXml As XmlElement In SingleDCL("DCL " & SubLines(subloop))
                    MultiSingleData.Add(DataXml)
                Next
                subloop += 1
            End If
        Loop
        Return MultiSingleData
    End Function
    ''' <summary>
    ''' 多行DCL的处理
    ''' </summary>
    ''' <param name="SubLines">
    ''' 如果是向数据部加入数据的话,这个参数为空,如果是过程里面用到的参数的话,这里把过程节点传入
    ''' </param>
    ''' <remarks></remarks>
    Shared Function TreeDCL(ByVal SubLines As List(Of String)) As XmlElement
        Dim TreeDataXml As XmlElement = mXmlDocument.CreateElement("TREEDATA")
        Dim BaseXml As XmlElement = TreeDataXml
        Dim StrWords As List(Of String)
        Dim DataString As String
        '防止层号省略的情况,如果发现层号省略,则使用上一次的层号
        Dim LayNo As String = "1"
        Dim BaseLayNo As Byte = 0
        Dim CurrentLayNo As Byte = 0
        Dim SingleComment As String = String.Empty
        SingleComment = GetComment(SubLines(0))
        TreeDataXml.SetAttribute("COMMENT", SingleComment)
        '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
        If GlobalCommentList.Count > 0 Then
            For Each StrComment As String In GlobalCommentList
                Dim CommentListXML As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                CommentListXML.SetAttribute("TEXT", StrComment)
                TreeDataXml.AppendChild(CommentListXML)
            Next
            GlobalCommentList.Clear()
        End If
        '第一行根节点
        StrWords = GetSyntaxToken(ClearComment(SubLines(0)))
        TreeDataXml = clsDataDefine.SetDataAttr(TreeDataXml, StrWords, 2)
        If Not SingleComment = String.Empty Then
            TreeDataXml.SetAttribute("COMMENT", SingleComment)
        End If
        TreeDataXml.SetAttribute("LayNo", StrWords(1))
        BaseXml = TreeDataXml
        For SubLoop As Byte = 2 To SubLines.Count
            '进行一些注释的处理工作
            DataString = SubLines(SubLoop - 1)
            SingleComment = ""
            If InStr(DataString, "*/") > 0 Then
                SingleComment = GetComment(DataString)
                DataString = ClearComment(DataString)
            End If
            StrWords = GetSyntaxToken(DataString)
            Dim SingleDataXml As XmlElement = mXmlDocument.CreateElement("SINGLEDATA")
            If Not SingleComment = String.Empty Then
                SingleDataXml.SetAttribute("COMMENT", SingleComment)
            End If
            Select Case True
                Case StrWords(0) = "%INCLUDE"
                    SingleDataXml = mXmlDocument.CreateElement("INCLUDE")
                    If SingleComment <> String.Empty Then SingleDataXml.SetAttribute("COMMENT", SingleComment)
                    SingleDataXml.SetAttribute("TYPE", "COPYBOOK")
                    SingleDataXml.SetAttribute("COPYBOOKNAME", StrWords(1))
                    '设置COPY的开始层号和结束层号
                    clsCopyBook.SetCopyBookByCopyBookInfoDic(SingleDataXml)
                    TreeDataXml.AppendChild(SingleDataXml)
                Case IsNumeric(StrWords(0))
                    '如果是层号的话
                    SingleDataXml.SetAttribute("LayNo", StrWords(0))
                    LayNo = StrWords(0)
                    SingleDataXml = clsDataDefine.SetDataAttr(SingleDataXml, StrWords, 1)
                    '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
                    If GlobalCommentList.Count > 0 Then
                        For Each StrComment As String In GlobalCommentList
                            Dim CommentListXML As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                            CommentListXML.SetAttribute("TEXT", StrComment)
                            SingleDataXml.AppendChild(CommentListXML)
                        Next
                        GlobalCommentList.Clear()
                    End If
                Case HasTOKEN("DEF", StrWords) And SubLoop = SubLines.Count
                    '如果不是层号的话,可能是DEF
                    'DEF式样：数据部-整理
                    '一般情况下面，这样的数据不存在
                    'DCL  KIJUNBI       PIC '(8)9'  INIT('0'),
                    '     KIJUNBI_YM    PIC '(6)9'  DEF KIJUNBI,
                    '     KIJUNBI4      PIC '(4)9'  DEF KIJUNBI POS(3);
                    '这种情况被MultiSingleDCL所捕获。
                    Dim DEFDataXml As XmlElement = mXmlDocument.CreateElement("SINGLEDATA")
                    If Not SingleComment = String.Empty Then
                        DEFDataXml.SetAttribute("COMMENT", SingleComment)
                    End If
                    DEFDataXml = clsDataDefine.SetDataAttr(DEFDataXml, StrWords, 0)
                    '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
                    If GlobalCommentList.Count > 0 Then
                        For Each StrComment As String In GlobalCommentList
                            Dim CommentListXML As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                            CommentListXML.SetAttribute("TEXT", StrComment)
                            DEFDataXml.AppendChild(CommentListXML)
                        Next
                        GlobalCommentList.Clear()
                    End If
                    mDataNode.AddData(TreeDataXml)
                    mDataNode.AddData(DEFDataXml)
                Case Else
                    '其他情况
                    SingleDataXml.SetAttribute("LayNo", LayNo)
                    SingleDataXml = clsDataDefine.SetDataAttr(SingleDataXml, StrWords, 0)
                    '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
                    If GlobalCommentList.Count > 0 Then
                        For Each StrComment As String In GlobalCommentList
                            Dim CommentListXML As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                            CommentListXML.SetAttribute("TEXT", StrComment)
                            SingleDataXml.AppendChild(CommentListXML)
                        Next
                        GlobalCommentList.Clear()
                    End If
            End Select

            If BaseXml.Name = "INCLUDE" Then
                BaseLayNo = clsCopyBookList.GetCopyBookInfoByName(BaseXml.GetAttribute("COPYBOOKNAME")).LastLayNo
            Else
                BaseLayNo = BaseXml.GetAttribute("LayNo")
            End If

            If SingleDataXml.Name = "INCLUDE" Then
                CurrentLayNo = clsCopyBookList.GetCopyBookInfoByName(SingleDataXml.GetAttribute("COPYBOOKNAME")).FirstLayNo
            Else
                CurrentLayNo = SingleDataXml.GetAttribute("LayNo")
            End If


            Dim RtnSingleList As New List(Of XmlElement)
            Dim strName As String = SingleDataXml.GetAttribute("NAME")
            '(I,J,K) CHAR(10)    
            If strName.StartsWith("(") And strName.EndsWith(")") Then
                strName = Mid(strName, 2, strName.Length - 2)
                Dim strNameArray As String() = strName.Split(",")
                For Each strSubName As String In strNameArray
                    Dim NewSubData As XmlElement = SingleDataXml.CloneNode(True)
                    NewSubData.SetAttribute("NAME", strSubName)
                    RtnSingleList.Add(NewSubData)
                Next
            Else
                RtnSingleList.Add(SingleDataXml)
            End If

            '根据当前处理节点的层号和基准层号来确定层次关系
            If CurrentLayNo > BaseLayNo Then
                '当前层号比基准层号大的时候，则是父节点处理子节点的过程
                For Each DataNode As XmlElement In RtnSingleList
                    BaseXml.AppendChild(DataNode)
                Next
            End If
            If CurrentLayNo = BaseLayNo Then
                '当前节点和基准节点同样层号时，表示基准节点和当前操作节点是兄弟关系
                For Each DataNode As XmlElement In RtnSingleList
                    BaseXml.ParentNode.AppendChild(DataNode)
                Next
            End If
            If CurrentLayNo < BaseLayNo Then
                '当前层号比基准层号小的时候，则是子节点处理完后回到上层父节点的过程
                Dim SameLayNoXml As XmlElement = BaseXml
                Do While True
                    If SameLayNoXml.Name = "INCLUDE" Then
                        BaseLayNo = clsCopyBookList.GetCopyBookInfoByName(SameLayNoXml.GetAttribute("COPYBOOKNAME")).FirstLayNo
                    Else
                        BaseLayNo = SameLayNoXml.GetAttribute("LayNo")
                    End If
                    If BaseLayNo = CurrentLayNo Or SameLayNoXml.ParentNode Is Nothing Then
                        Exit Do
                    Else
                        '向上寻找当前节点的兄弟节点
                        SameLayNoXml = SameLayNoXml.ParentNode
                    End If
                Loop
                '找到兄弟节点后，将自己放在兄弟节点的父节点下面
                For Each DataNode As XmlElement In RtnSingleList
                    SameLayNoXml.ParentNode.AppendChild(DataNode)
                Next
            End If
            '将当前节点设置为基准节点
            BaseXml = RtnSingleList(0)
        Next
        Return TreeDataXml
    End Function
    ''' <summary>
    ''' 设定节点属性结构
    ''' </summary>
    ''' <param name="mNode"></param>
    ''' <param name="strWords"></param>
    ''' <param name="NameIndex"></param>
    ''' <remarks></remarks>
    Public Shared Function SetDataAttr(ByVal mNode As XmlElement, ByVal strWords As List(Of String), ByVal NameIndex As Byte) As XmlNode
        '1) 末尾符号已经除去
        Dim DataName As String
        DataName = strWords(NameIndex)
        If DataName = "1" Then
            '发现非集团项目增加了阶层号的现象
            NameIndex += 1
            DataName = strWords(NameIndex)
        End If
        '对于LIKE关键字的采集
        If HasTOKEN("LIKE", strWords) Then
            mNode.SetAttribute("LIKE", strWords(GetTokenPos("LIKE", strWords)))
        End If
        If InStr(DataName, "(") > 0 And InStr(DataName, ")") > 0 Then
            '数组
            If InStr(DataName, "(") = 1 Then
                mNode.SetAttribute("NAME", DataName)
                mNode.SetAttribute("REPEAT", 1)
            Else
                Dim strRepeat As String = Mid(DataName, InStr(DataName, "(") + 1).Replace(")", String.Empty)
                Dim strName As String = Mid(DataName, 1, InStr(DataName, "(") - 1)
                If strRepeat.Contains(":") Then
                    '以非1为下标开始的数组的重复度处理(0:100)或者(5:10)这样的数据 
                    mDataNode.UnderBoundNotFrom1.Add(strName, CInt(strRepeat.Split(":")(0)))
                    strRepeat = CInt(strRepeat.Split(":")(1)) - CInt(strRepeat.Split(":")(0)) + 1
                    GlobalCommentList.Add("*WARNING:ZERO-BASE ARRAY")
                    LogWriter.WriteLine("*WARNING:ZERO-BASE ARRAY")
                    LogWriter.WriteLine("*NAME:" & strName)
                End If
                If strRepeat.TrimStart("0") = "1" Then
                    mNode.SetAttribute("REPEAT", 1)
                Else
                    mNode.SetAttribute("REPEAT", strRepeat)
                End If
                mNode.SetAttribute("NAME", strName)
            End If
        Else
            '非数组
            mNode.SetAttribute("NAME", DataName)
            mNode.SetAttribute("REPEAT", 1)
        End If
        SetNotDataItem(strWords, NameIndex, mNode)
        Return clsDataObject.SetDataType(mNode, strWords)
    End Function
    ''' <summary>
    ''' 对于非数据项目的设定（例如文件，内部函数和外部函数）
    ''' </summary>
    ''' <param name="StrWords"></param>
    ''' <param name="NameIndex"></param>
    ''' <param name="mNode"></param>
    ''' <remarks></remarks>
    Shared Sub SetNotDataItem(ByVal StrWords As List(Of String), ByVal NameIndex As Byte, ByVal mNode As XmlElement)
        If (HasTOKEN("STREAM", StrWords) Or HasTOKEN("RECORD", StrWords)) AndAlso _
           (HasTOKEN("INPUT", StrWords) Or HasTOKEN("OUTPUT", StrWords) Or HasTOKEN("UPDATE", StrWords)) Or _
           (HasTOKEN("PRINT", StrWords)) Then
            mNode.SetAttribute("TYPE", "FILEDEFINE")
            If HasTOKEN("STREAM", StrWords) Then mNode.SetAttribute("FILEFORMAT", "STREAM")
            If HasTOKEN("RECORD", StrWords) Then mNode.SetAttribute("FILEFORMAT", "RECORD")
            If HasTOKEN("INPUT", StrWords) Then mNode.SetAttribute("FILEIO", "INPUT")
            If HasTOKEN("OUTPUT", StrWords) Then mNode.SetAttribute("FILEIO", "OUTPUT")
            If HasTOKEN("UPDATE", StrWords) Then mNode.SetAttribute("FILEIO", "UPDATE")
            mNode.SetAttribute("FILENAME", StrWords(NameIndex))
            'INPUT、OUTPUT 和 PRINT 可以同时出现
            If HasTOKEN("PRINT", StrWords) Then
                mNode.SetAttribute("ISPRINT", "True")
            Else
                mNode.SetAttribute("ISPRINT", "False")
            End If
        End If
        'BUILTIN
        If HasTOKEN("BUILTIN", StrWords) Then
            mNode.SetAttribute("TYPE", "BUILTINDEFINE")
        End If
        'EXTERNAL ENTRY
        If (HasTOKEN("ENTRY", StrWords) And HasTOKEN("EXTERNAL", StrWords)) Or _
           (HasTOKEN("EXT", StrWords) And HasTOKEN("ENTRY", StrWords)) Then
            mNode.SetAttribute("TYPE", "ENTRYDEFINE")
        End If
    End Sub
End Class
